﻿using UnityEngine;

/// <summary>
/// 一个简单的mono单例基类,提供基本的单例管理功能。
/// 子类可以继承此类并扩展其功能。
/// </summary>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    // 判断消息中心是否已经销毁，防止在游戏结束时，消息中心先销毁，再销毁角色，导致消息中心重新实例化
    private static bool isQuit = false;

    #region 单例实现
    /// 单例实例
    private static T m_Instance;

    /// 获取单例实例
    public static T Instance
    {
        get
        {
            if (m_Instance == null && !isQuit)
            {
                // 尝试在场景中查找实例
                m_Instance = FindObjectOfType<T>();

                if (m_Instance == null)
                {
                    // 如果场景中没有找到，则创建一个新的GameObject并添加该组件
                    GameObject singletonObject = new GameObject(typeof(T).Name);
                    m_Instance = singletonObject.AddComponent<T>();
                }

                // 确保单例在场景切换时不被销毁
                DontDestroyOnLoad(m_Instance.gameObject);
            }

            return m_Instance;
        }
    }
    #endregion

    protected virtual void Awake()
    {
        // 确保只存在一个实例
        if (m_Instance == null)
        {
            m_Instance = this as T;
            OnInit();
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            // 如果已经存在实例，则销毁当前实例
            if (this != m_Instance)
            {
                Destroy(gameObject);
            }
        }
    }

    //初始化
    protected virtual void OnInit()
    {

    }

    #region 单例清理

    protected virtual void OnDestroy()
    {
        if (m_Instance != null && m_Instance == this)
        {
            OnCleanUp();
            m_Instance = null;
            isQuit = true;
        }
    }

    // 清理资源
    protected virtual void OnCleanUp() { }

    #endregion
}